fix(logging): make access-log http.route resolution framework-robust#16
Merged
Conversation
AccessLogMiddleware._route_template read the matched route's `.path`, which newer Starlette (1.x — what the service container actually resolves at build time) renamed to `.path_format` (`.path` is None) — so EVERY request logged http.route="__unmatched__", silently defeating per-route observability. The unit test missed it: its toy app uses a small middleware stack and directly-added routes where `.path` is still set. Prefer scope["route"] (the router records it) and read path_format-or-path, with a fallback that maps scope["endpoint"] back to its route. Verified resolving real templates (/auth/providers, /authz/resolve, /admin/activity; 404 -> __unmatched__) on BOTH starlette 0.52 and 1.3. Adds a regression test pinning path_format/path. Why now: the shipped image installs latest-within-pyproject (the Dockerfile resolves from pyproject, not the frozen lock), so 0.13.0's container already runs starlette 1.x — the prod access-log is broken until this lands. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
AccessLogMiddleware._route_templateread the matched route's.path. Newer Starlette(1.x) renamed that to
.path_format(.pathisNone), so every request loggedhttp.route="__unmatched__"— silently defeating per-route observability (latencydashboards, cardinality baselining, the documented
http.accesscontract).This is already affecting shipped 0.13.0: the service Dockerfile resolves deps from
pyproject.toml(it neverCOPYsuv.lock), so the container installs the latestcompatible starlette (1.x), not the locked 0.52.1.
make start(which honors the lock)masked it locally.
Fix
Prefer
scope["route"](the router records it) and readpath_format→path, with afallback that maps
scope["endpoint"]back to its route. Robust across the framework'srouting reworks.
Verification
Real-app
TestClientcapture on both starlette 0.52.1 and 1.3.1:Plus a regression test pinning the
path_format/pathrobustness; service suite 227 ✓.Follow-ups (separate)
COPY uv.lock+uv sync --frozenfor reproducible builds (the image currently ignores the lock).🤖 Generated with Claude Code